package com.quxue.im.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.quxue.im.common.Const;
import com.quxue.im.common.enums.*;
import com.quxue.im.entity.ChatMsg;
import com.quxue.im.entity.ChatUser;
import com.quxue.im.mapper.ChatMsgMapper;
import com.quxue.im.req.chat.ChatMsgReq;
import com.quxue.im.service.IChatMsgService;
import com.quxue.im.service.IChatUserService;
import com.quxue.im.util.RedisUtils;
import com.quxue.im.vo.chat.ChatMsgVo;
import com.quxue.im.vo.push.*;
import com.quxue.im.ws.BootWebSocketHandler;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 聊天消息 服务实现类
 * </p>
 *
 * @author jinken
 * @since 2023-11-10
 */
@Service
public class ChatMsgServiceImpl extends ServiceImpl<ChatMsgMapper, ChatMsg> implements IChatMsgService {


    @Resource
    private RedisUtils redisUtils;

    @Resource
    private BootWebSocketHandler bootWebSocketHandler;

    @Resource
    private IChatUserService chatUserService;

    @Override
    public void pushNotification(PushParamVo pushParamVo, PushNoticeEnum noticeType) {


        //组装消息的内容
        PushNoticeVo pushNoticeVo = new PushNoticeVo();

        switch (noticeType){
            //好友申请
            case FRIEND_APPLY:{
                Long applyCount = redisUtils.increment(Const.REDIS_FRIEND_NOTICE + pushParamVo.getToId(), 1);
                pushNoticeVo.getFriendApply().put("count",applyCount);
                break;
            }
            case TOPIC_RED:{
                System.out.println("TOPIC_RED");
                break;
            }

            case TOPIC_REPLY:{
                System.out.println("TOPIC_REPLY");
                break;
            }
        }
        //创建PushBodyVo
        PushBodyVo pushBodyVo = new PushBodyVo(IdUtil.getSnowflakeNextId(), PushBodyEnum.NOTICE,pushNoticeVo);
        //发送消息
        push(pushParamVo.getToId(),pushBodyVo);
    }

    @Override
    public void pushMessage(PushParamVo from, PushMsgEnum msgType) {
        System.out.println("noticeVo = " + from);

        System.out.println("msgType = " + msgType);


        PushMsgVo pushMsgVo = new PushMsgVo();
        pushMsgVo.setContent(from.getContent());
        pushMsgVo.setMsgType(msgType.getCode());

        PushBodyVo pushBodyVo = new PushBodyVo(from.getMsgId(),PushBodyEnum.MSG,pushMsgVo);
        pushBodyVo.setFromInfo(BeanUtil.toBean(from, PushFromVo.class).setUserType(from.getUserType().getCode()));
        //推送消息
        this.push(from.getToId(),pushBodyVo);
    }

    @Override
    public ChatMsgVo sendFriendMsg(ChatMsgReq msgReq) {

        /**
         * 处理步骤
         * 1，检查用户是否你好友（你删除了对方）
         * 2，检查你是否是对方好友（对方删除了你）
         * 3，检查是否你是否对方的黑名单
         * 4，检查好友是否注销
         * 5，保存消息到
         * 6，发送
         */

        ChatMsg chatMsg = saveMsg(msgReq);


        //查询发送人信息
        ChatUser sendUser = chatUserService.getById(StpUtil.getLoginIdAsLong());

        //返回消息发送消息结果
        ChatMsgVo chatMsgVo = new ChatMsgVo();
        chatMsgVo.setMsgId(chatMsg.getId());
        chatMsgVo.setStatus(MsgStatusEnum.NORMAL);
        chatMsgVo.setUserInfo(sendUser);


        //封装消息参数
        PushParamVo pushParamVo = new PushParamVo();
        pushParamVo.setUserId(StpUtil.getLoginIdAsLong());
        pushParamVo.setMsgId(chatMsg.getId());
        pushParamVo.setToId(msgReq.getUserId());
        pushParamVo.setNickName(sendUser.getNickName());
        pushParamVo.setPortrait(sendUser.getPortrait());
        pushParamVo.setContent(msgReq.getContent());

        //推送消息
        this.pushMessage(pushParamVo,msgReq.getMsgType());

        return chatMsgVo;
    }


    /**
     * 保存消息
     * @param msgReq
     */
    public ChatMsg saveMsg(ChatMsgReq msgReq){
        ChatMsg chatMsg = new ChatMsg();
        chatMsg.setId(IdUtil.getSnowflakeNextId());
        chatMsg.setMsgType(msgReq.getMsgType().getCode());
        chatMsg.setContent(msgReq.getContent());
        chatMsg.setFromId(StpUtil.getLoginIdAsLong());
        chatMsg.setToId(msgReq.getUserId());
        chatMsg.setCreateTime(LocalDateTime.now());
        chatMsg.setTalkType(PushTalkEnum.SINGLE.getCode());
        this.save(chatMsg);
        return chatMsg;
    }

    public void push(Long userId,PushBodyVo pushBodyVo){
        System.out.println("pushBodyVo = " + pushBodyVo);

        //将json转换为json字符串
        String content = JSON.toJSONString(pushBodyVo);
//        String s = JSON.toJSONString(pushBodyVo, true);
//        System.out.println(s);

        //使用WebSocket发送消息给好友
        bootWebSocketHandler.sendMsg(userId,content);

        //离线消息，好友不在线，如果上线后，可以去Redis拉取消息
        //消息key
        String msgKey = StrUtil.format(Const.REDIS_MSG,userId,pushBodyVo.getMsgId());
        //发送离线 7天有效
        redisUtils.set(msgKey,content,7, TimeUnit.DAYS);

    }

    @Override
    public void pullMsg(Long userId) {

        //获取当前用户的所有key
        String redisKey = StrUtil.format(Const.REDIS_MSG,userId,"*");

        Set<String> keys = redisUtils.keys(redisKey);
        if (CollUtil.isEmpty(keys)){
            return;
        }
        //获取所有key的消息
        List<String> contents = redisUtils.multiGet(keys);

       //循环发送
        for (String content : contents) {
            bootWebSocketHandler.sendMsg(userId,content);
            System.out.println("离线消息 = " + content);
        }

        //删除当前聊天的所有数据
        redisUtils.delete(keys);

    }
}
